package uy.org.softtech.cssuite.web.reportes;

import static org.apache.commons.lang.StringUtils.trimToEmpty;
import static org.apache.commons.lang.StringUtils.startsWithIgnoreCase;
import static uy.org.softtech.cssuite.helpers.HelperFechaHora.fechaLarga;
import static uy.org.softtech.cssuite.helpers.HelperSeguridad.usuarioActual;

import java.awt.Color;
import java.io.StringReader;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.htmlparser.jericho.Source;
import net.minidev.json.JSONArray;

import org.apache.log4j.Logger;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.view.document.AbstractPdfView;

import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfBoolean;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfNumber;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class ReportePdf extends AbstractPdfView {
	
	private Logger log = Logger.getLogger(getClass());
	
	protected final Font fuente = new Font(Font.TIMES_ROMAN, 8, Font.NORMAL);
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.view.document.AbstractPdfView#newDocument()
	 */
	@Override
	protected Document newDocument() {
		return new Document(PageSize.A4.rotate());
	}

	@Override
	@SuppressWarnings("unchecked")
	protected void buildPdfDocument(Map<String, Object> model, Document document, PdfWriter writer, HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			//Extraigo datos del modelo
			String titulo = (String) model.get("REPORTE_TITULO");
			String mensaje = (String) model.get("REPORTE_MENSAJE");
			JSONArray cabezales = (JSONArray) model.get("REPORTE_CABEZALES");
			JSONArray celdas = (JSONArray) model.get("REPORTE_CELDAS");
			
			int columnas = cabezales.size() - 1;	//Para excluir la última columna que tiene los links
			
			//Propiedades del documento (Autor, Fecha de creación, Título, etc.)
			String autor = usuarioActual().convierteNombreCompleto();
			document.addAuthor(autor);
			document.addCreationDate();
			document.addCreator(autor);
			document.addTitle(titulo);
			
			//Propiedades de impresión del documento (Número de copias, Ajustar a la ventana, etc.)
			writer.setPdfVersion(PdfWriter.VERSION_1_7);
			writer.addViewerPreference(PdfName.FITWINDOW, PdfBoolean.PDFTRUE);
			writer.addViewerPreference(PdfName.HIDEMENUBAR, PdfBoolean.PDFTRUE);
			writer.addViewerPreference(PdfName.HIDEWINDOWUI, PdfBoolean.PDFTRUE);
			writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
	        writer.addViewerPreference(PdfName.NUMCOPIES, new PdfNumber(1));
	        writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
			
			//Obtengo imágenes de logos
			WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
			String logoAplicacion = context.getResource("classpath:/uy/org/softtech/cssuite/web/recursos/img/cssuite/cssuite.png").getFile().getCanonicalPath();
			String logoEmpresa = context.getResource("classpath:/uy/org/softtech/cssuite/web/recursos/img/cssuite/softtech.png").getFile().getCanonicalPath();
			
			//Logo de la aplicación
			Image aplicacion = Image.getInstance(logoAplicacion);
			aplicacion.setSpacingAfter(10);
			aplicacion.setAlignment(Image.LEFT | Image.UNDERLYING);
			aplicacion.setBorder(Image.BOX);
			aplicacion.setBorderWidth(10);
			aplicacion.setBorderColor(Color.WHITE);
			aplicacion.scaleToFit(99, 58);
			document.add(aplicacion);
			
			//Logo de la empresa
			Image softtech = Image.getInstance(logoEmpresa);
			softtech.setSpacingAfter(10);
			softtech.setAlignment(Image.RIGHT | Image.UNDERLYING);
			softtech.setBorder(Image.BOX);
			softtech.setBorderWidth(10);
			softtech.setBorderColor(Color.WHITE);
			softtech.scaleToFit(99, 58);
			document.add(softtech);
			
			document.add(new Paragraph(Chunk.NEWLINE));
			
			//Título del reporte
			Paragraph paragraph = new Paragraph(new Phrase(new Chunk(titulo, fuente)));
			paragraph.setAlignment(Element.ALIGN_LEFT);
			paragraph.setSpacingBefore(60);
			document.add(paragraph);
			
			Paragraph dummy = new Paragraph("\u00a0", fuente);
	        dummy.setLeading(-18);
	        document.add(dummy);
	         
			//Fecha del reporte
			paragraph = new Paragraph(new Phrase(new Chunk(fechaLarga(), fuente)));
			paragraph.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph);
			
			document.add(new Paragraph(Chunk.NEWLINE));
			
			//Tabla
			PdfPTable tabla = new PdfPTable(columnas);
			tabla.getDefaultCell().setUseAscender(true);
	        tabla.getDefaultCell().setUseDescender(true);
	        tabla.getDefaultCell().setBackgroundColor(Color.WHITE);
	        tabla.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
	        tabla.setHeaderRows(1);
	        tabla.setKeepTogether(true);
	        tabla.setSpacingAfter(10);
	        tabla.setSpacingBefore(10);
	        tabla.setWidthPercentage(100f);
	        
	        //table.setWidths(new float[]{	TWENTY, FIFTHTEEN, FIFTHTEEN, FIVE, FIFTHTEEN, TEN, TWENTY	});
	        
	        //Cabezales
			for(int idx = 0; idx < columnas; idx++) {
	        	String texto = (String) cabezales.get(idx);
	        	PdfPCell cell = new PdfPCell(new Phrase(new Chunk(texto, fuente)));
	        	cell.setHorizontalAlignment(Element.ALIGN_CENTER);
	        	tabla.addCell(cell);
	        }
			
			//Datos
			for(int idx = 0; idx < celdas.size(); idx++) {
				List<String> datos = (List<String>) celdas.get(idx);
				for(int columna = 0; columna < columnas; columna++) {
					String texto = trimToEmpty(datos.get(columna));
					if(startsWithIgnoreCase(texto, "<span")) {		//Código HTML
						Source source = new Source(new StringReader(texto));
						net.htmlparser.jericho.Element element = source.getFirstElement();
						texto = element.getAttributeValue("title");
					}
					PdfPCell cell = new PdfPCell(new Phrase(new Chunk(texto, fuente)));
			        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
			        tabla.addCell(cell);
				}
			}
			
			document.add(tabla);
			
			document.add(new Paragraph(Chunk.NEWLINE));
			
			//Mensaje
			paragraph = new Paragraph(new Phrase(new Chunk(mensaje, fuente)));
			paragraph.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph);
			
			//Generamos el nombre del archivo
			String archivo = UUID.randomUUID().toString() + ".pdf";
			response.setHeader("Content-Disposition", "attachment; filename=" + archivo);
			response.setHeader("Pragma", "no-cache");
		    response.setHeader("Cache-Control", "no-cache");
			response.setContentType("application/pdf");
		} catch (Throwable t) {
			log.error(t);
		}
	}

}
